Skip to content

Retry with rbf = -1 if tokens are dropped - #5080

Open
Shuwen-Fang wants to merge 1 commit into
mainfrom
token_dropping
Open

Retry with rbf = -1 if tokens are dropped#5080
Shuwen-Fang wants to merge 1 commit into
mainfrom
token_dropping

Conversation

@Shuwen-Fang

@Shuwen-Fang Shuwen-Fang commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Description

Currently, when ragged buffer is set, we drop any tokens that exceed the buffer size. This can occur if the dataset is very imbalanced.

This PR implements an optional flag to prevent token dropping. If it's set to true, then we will rerun the given layer if tokens are dropped with worse-case ragged buffer size to prevent token dropping.

BUGS: b/555278394

Tests

We saw retry successfully retries and has similar convergence to baseline when ragged buffer drops tokens (and diverges when retry is disabled), and when tokens were not dropped (rbf = 2) throughput is similar to baseline. Baseline experiments were executed on cl/974137029 for direct comparison. All workloads evaluated on 256 TPU chips (DeepSeek-V3 671B MoE).

Config XID Loss at Step 86 Average Throughput over Last 60 Steps (Tokens/s/device) Number of Retries (Logs) CMD (gPaste Link)
p4head rbf = -1 286646082 3.473 (ppl: 32.24) 631.26 (mean step: 12.98s) 0 (Dropless baseline) gPaste: deploy_p4head_7029_rbf_neg1
p4head rbf = 2 (No Retry) 286646089 3.481 (ppl: 32.50) 653.55 (mean step: 12.53s) 0 (No retry) gPaste: deploy_p4head_7029_rbf_2
pr rbf = -1 (No Retry) 286718316 3.457 (ppl: 31.72) 632.81 (mean step: 12.95s) 0 (Dropless baseline) gPaste: deploy_pr_6389_rbf_neg1
pr rbf = 0.125 (No Retry) 286646092 5.271 (ppl: 194.57) 949.74 (mean step: 8.63s) 0 (Dropping without retry; diverged) gPaste: deploy_cl_rbf_0p125_no_retry
pr rbf = 0.125 with retry 286621402 3.477 (train ppl: 32.35) 391.64 (mean step: 20.92s) 87 retries (All 87 steps retried; converged) gPaste: deploy_cl_rbf_0p125_retry
pr rbf = 2 with retry 286718340 3.468 (ppl: 32.07) 653.84 (mean step: 12.53s) 0 (0 overflows / 0 retries) gPaste: deploy_pr_6389_rbf_2_retry
pr rbf = 2 without retry 286719268 3.482 (ppl: 32.52) 653.48 (mean step: 12.54s) 0 (No retry comparison) gPaste: deploy_pr_6389_rbf_2_no_retry

Checklist

Before submitting this PR, please make sure (put X in square brackets):

  • I have performed a self-review of my code. For an optional AI review, add the gemini-review label.
  • I have necessary comments in my code, particularly in hard-to-understand areas.
  • I have run end-to-end tests tests and provided workload links above if applicable.
  • I have made or will make corresponding changes to the doc if needed, including adding new documentation pages to the relevant Table of Contents (toctree directive) as explained in our documentation.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a retry mechanism (retry_when_tokens_dropped) for Mixture of Experts (MoE) training, allowing the training step to be retried with a dropless buffer capacity if tokens are dropped due to ragged sort buffer overflow. The changes span configuration files, MoE routing layers, training loops, and unit tests. The review feedback highlights several critical issues: a performance regression caused by host-device synchronization on every step, a logging bug where metrics are overwritten during a retry, compatibility issues with pure NNX models due to the use of self.sow, a trivial unit test that does not actually execute the retry logic, and a JAX tracing anti-pattern when collecting intermediate metrics.

Comment thread src/maxtext/trainers/pre_train/train.py Outdated
Comment thread src/maxtext/layers/moe.py Outdated
Comment thread tests/unit/moe_test.py Outdated
Comment thread src/maxtext/trainers/pre_train/train.py Outdated
@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.55556% with 28 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/maxtext/trainers/pre_train/train.py 37.14% 16 Missing and 6 partials ⚠️
src/maxtext/layers/nnx_decoders.py 50.00% 3 Missing ⚠️
src/maxtext/utils/maxtext_utils.py 33.33% 1 Missing and 1 partial ⚠️
src/maxtext/layers/moe.py 94.73% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@Shuwen-Fang
Shuwen-Fang force-pushed the token_dropping branch 4 times, most recently from 6abb4a2 to b074035 Compare September 2, 2026 21:13
Comment thread src/maxtext/layers/moe.py Outdated
# capacity by leveraging the helper _truncate_matrix.
local_group_size = _truncate_matrix(local_group_size[:, None], buffer_size)[:, 0]
if num_expert_parallelism > 1:
has_overflow = jax.lax.psum(local_overflow, self._expert_parallelism_name) > 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have to check all (FS)DP ranks as well? DP rank 0 might not overflow for any EP but DP rank 1 would overflow - these ranks will have different values for has_overflow. Can we just all reduce over every device?

Comment thread tests/unit/maxtext_utils_test.py Outdated
)
self.assertEqual(donate_argnums, 0)

def test_donate_argnums_is_zero_with_retry_when_tokens_dropped(self):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does flipping the value of retry_when_tokens_drop change the signature of train? I'm not sure whats being tested here that is specific to retry_when_tokens_dropped

…rflow

Implements host-driven step replay for handling token dropping with HBM OOM protection:
- Pre-compiles both a candidate train step (using tuned ragged_buffer_factor) and a dropless train step (using dropless buffer).
- Disables state donation (donate_argnums = ()) when retry_when_tokens_dropped is enabled so input state is preserved for replay.
- In the training loop, evaluates metrics['has_moe_overflow'] on the host. If True, discards candidate state, deallocates its device buffers, and replays the step with the dropless executable.
- All-reduces local_overflow across all mesh axes (tuple(self.mesh.axis_names)) inside shard_map to ensure all (FS)DP ranks observe identical overflow status, avoiding multi-host hangs.
- Configures dropless fallback with token chunking, optimization barrier, and full remat to fit worst-case buffer allocations in HBM.
- Eliminates jax.lax.cond control flow completely from the forward and backward graph, preserving compiler optimizations and cross-layer collective pipelining.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants